package obj;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

import mech.AttackQ;

import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;

import play.Things;
import util.Settings;

/**
 * Player class.
 * @author VincentLy
 */
public class Player extends Sprite{	
	
	private float hp;
	private boolean shoot;
	private boolean bulletheaven;
	private boolean usingMove;
	private boolean walkingFwd;
	private boolean walkingBwd;
	private boolean jumping;
	private boolean ducking;
	private boolean invincible;
	private long start;
	private long start2;
	private Timer invin;
	private Timer cooldown;
	
	public Player(float x,float y,int d,Image i) throws SlickException{
		super(x,y,d,i);
		hp = 500;
		bulletheaven = true;
		usingMove = false;
		invincible = false;
		walkingFwd = false;
		walkingBwd = false;
		jumping = false;
		ducking = false;
		cooldown = new Timer(5000,new ActionListener(){
			public void actionPerformed(ActionEvent e){
				bulletheaven = true;
				cooldown.stop();
			}
		});
		invin = new Timer(1500,new ActionListener(){
			public void actionPerformed(ActionEvent e){
				invincible = false;
				invin.stop();
			}
		});
	}
	
	/**
	 * Stops the walking animations.
	 * @author VincentLy
	 */
	public void stop(){
		if(!Settings.fwd.isStopped()){
			Settings.fwd.restart();
			Settings.fwd.stop();
		}	
		if(!Settings.bwd.isStopped()){
			Settings.bwd.restart();
			Settings.bwd.stop();
		}	
		setXVel(0);
		walkingFwd = false;
		walkingBwd = false;
	}
	
	/**
	 * Turns on forward animation.
	 * @author VincentLy
	 */
	public void walkFwd(){
		if(!Settings.bwd.isStopped()){
			Settings.bwd.restart();
			Settings.bwd.stop();
		}	
		if(Settings.fwd.isStopped())			
			Settings.fwd.start();
		walkingBwd = false;
		walkingFwd = true;
	}
	
	/**
	 * Turns on backward animation.
	 * @author VincentLy
	 */
	public void walkBwd(){
		if(!Settings.fwd.isStopped()){
			Settings.fwd.restart();
			Settings.fwd.stop();
		}	
		if(Settings.bwd.isStopped())			
			Settings.bwd.start();
		walkingFwd = false;
		walkingBwd = true;		
	}
	
	/**
	 * @return true if player is ducking
	 * @author VincentLy
	 */
	public boolean isDucking(){return ducking;}
	
	/**
	 * Activates cooldown timer for Bullet Heaven.
	 * @author VincentLy
	 */
	public void useBulletHeaven(){
		bulletheaven = false;
		start2 = System.currentTimeMillis();
		cooldown.start();
	}

	/**
	 * @return true if the user can use Bullet Heaven.
	 */
	public boolean canUseBulletHeaven(){return bulletheaven;}
	
	/**
	 * Makes the player duck.
	 * @author VincentLy
	 */
	public void duck(){
		ducking = true;
		stop();
	}
	
	/**
	 * Makes the player rise from ducking.
	 * @author VincentLy
	 */
	public void rise(){ducking = false;}
	
	/**
	 * Makes the player shoot.
	 * @author VincentLy
	 */
	public void shoot(){shoot = true;}
	
	/**
	 * Ends the player shooting.
	 * @author VincentLy
	 */
	public void fin(){shoot = false;}
	
	/**
	 * Notes that the player has landed.
	 * @author VincentLy
	 */
	public void land(){jumping = false;}
	
	/**
	 * Notes that the player has initiated a jump.
	 * @author VincentLy
	 */
	public void jump(){jumping = true;}
	
	/**
	 * @param h - hp
	 * @author VincentLy
	 */
	public void setHP(float h){hp = h;}
		
	/**
	 * @return hp
	 * @author VincentLy
	 */
	public float hp(){return hp;}
	
	/**
	 * @return the current move
	 * @author VincentLy
	 */
	public boolean isUsingMove(){return usingMove;}
	
	/**
	 * @return invincibility
	 * @author VincentLy
	 */
	public boolean isInvincible(){return invincible;}
	
	/**
	 * @return animation start time
	 * @author VincentLy
	 */
	public long start(){return start;}
	
	/**
	 * @param b - if using a move
	 * @author VincentLy
	 */
	public void useMove(boolean b){usingMove = b;}
	
	/**
	 * Starts the invincibility.
	 * @author VincentLy
	 */
	public void invincible(){
		invincible = true;
		start = System.currentTimeMillis();
		invin.start();
	}
	
	/**
	 * Draws the player and related aspects.
	 * @author VincentLy
	 */
	public void draw(Graphics g){
		boolean draw = true;
		if(Things.player.isInvincible())			
			if(Math.random()>.5)
				draw = false;
		if(draw){
			if(shoot){
				if(AttackQ.lastMove().equals("Bullet Heaven"))
					Settings.heaven.draw(left()-100,top()-300);
				if(dir() == 1)			
					Settings.shoot.draw(left()-15,top()-30);
				else
					Settings.backshoot.draw(left()-45,top()-30);
			}	
			else if(jumping){
				if(dir() == 1)
					Settings.jump.draw(left()-15,top()-30);
				else
					Settings.backjump.draw(left()-15,top()-30);
			}
			else if(ducking){
				if(dir() == 1)
					Settings.crouch.draw(left()-35,top()-30);
				else
					Settings.backcrouch.draw(left()-20,top()-30);
			}
			else if(walkingFwd)
				Settings.fwd.draw(left()-15,top()-30);		
			else if(walkingBwd)		
				Settings.bwd.draw(left()-25,top()-30);
			else 
				super.draw(g);
		}
		Settings.hpbar.draw(-Settings.tx,-Settings.ty);
		g.setColor(Color.white);
		g.fillRoundRect(-Settings.tx+55,-Settings.ty+65,hp/500*120,8,5);	
		g.drawString("Skills",-Settings.tx+50-g.getFont().getWidth("Skills")/2,-Settings.ty+100);
		Settings.heaven.getScaledCopy(50,50).draw(-Settings.tx+27,-Settings.ty+135);
		if(cooldown.isRunning())
			g.drawArc(-Settings.tx+25,-Settings.ty+130,50,50,0,(float) (360*(System.currentTimeMillis()-start2)/5000.0));
		else
			g.drawArc(-Settings.tx+25,-Settings.ty+130,50,50,0,360);
		g.drawString("Gold: " + Things.gold,-Settings.tx+150,-Settings.ty+20);
	}
}